#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
typedef double db;
inline int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); }
	while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+ch-'0'; ch=getchar(); }
	return x*f;
}
const int MAXN=2e5+10;
int n,m,belog[MAXN],ans,stac[MAXN],top;
int getfa(int x)
{
	return belog[x]==x?x:belog[x]=getfa(belog[x]);
}
struct edge
{
	int u,v,a,b;
	bool operator<(const edge k)const
	{
		return a<k.a;
	}
}e[MAXN];
struct LCT
{
	int c[MAXN][2],fa[MAXN],mx[MAXN],val[MAXN];
	bool rev[MAXN];
	void push_up(int o)
	{
		mx[o]=o;
		if(val[mx[c[o][0]]]>val[o])mx[o]=mx[c[o][0]];
		if(val[mx[c[o][1]]]>val[mx[o]])mx[o]=mx[c[o][1]];
		return;
	}
	void reverse(int o)
	{
		rev[o]^=1;
		swap(c[o][0],c[o][1]);
		return;
	}
	void push_down(int o)
	{
		if(rev[o])
		{
			reverse(c[o][0]);
			reverse(c[o][1]);
			rev[o]=false;
		}
		return;
	}
	bool isroot(int o)
	{
		return !(c[fa[o]][0]==o||c[fa[o]][1]==o);
	}
	void rotate(int x)
	{
		int y=fa[x],z=fa[y],dy=c[y][1]==x,dz=c[z][1]==y;
		if(!isroot(y))c[z][dz]=x;
		c[y][dy]=c[x][dy^1];
		fa[c[y][dy]]=y;
		c[x][dy^1]=y;
		fa[y]=x;
		fa[x]=z;
		push_up(y);
		return;
	}
	void splay(int x)
	{
		stac[top=1]=x;
		for(int i=x;!isroot(i);i=fa[i])stac[++top]=fa[i];
		while(top)push_down(stac[top--]);
		while(!isroot(x))
		{
			int y=fa[x],z=fa[y];
			if(!isroot(y))
			{
				if(c[y][0]==x^c[z][0]==y)rotate(x);
				else rotate(y);
			}
			rotate(x);
		}
		push_up(x);
		return;
	}
	void access(int o)
	{
		for(int i=0;o;i=o,o=fa[o])
			splay(o),c[o][1]=i,push_up(o);
		return;
	}
	void makeroot(int o)
	{
		access(o);
		splay(o);
		reverse(o);
		return;
	}
	int findroot(int o)
	{
		access(o);
		splay(o);
		while(c[o][0])o=c[o][0];
		return o;
	}
	void link(int x,int y)
	{
		makeroot(x);
		fa[x]=y;
		return;
	}
	void cut(int x,int y)
	{
		makeroot(x);
		access(y);
		splay(y);
		c[y][0]=fa[x]=0;
		push_up(y);
		return;
	}
	int query(int x,int y)
	{
		makeroot(x);
		access(y);
		splay(y);
		return mx[y];
	}
	void solve()
	{
		for(int i=1;i<=m;++i)
		{
			int a=getfa(e[i].u),b=getfa(e[i].v);
			if(a==b)
			{
				int t=query(e[i].u,e[i].v);
				if(val[t]>e[i].b)
				{
					cut(t,e[t-n].u);
					cut(t,e[t-n].v);
				}
				else
				{
					if(getfa(1)==getfa(n))ans=min(ans,e[i].a+val[query(1,n)]);
					continue;
				}
			}
			else belog[a]=b;
			val[n+i]=e[i].b;
			mx[n+i]=n+i;
			link(n+i,e[i].u);
			link(n+i,e[i].v);
			if(getfa(1)==getfa(n))ans=min(ans,e[i].a+val[query(1,n)]);
		}
		return;
	}
}T1;
int main()
{
	n=read();m=read();
	ans=INF;
	for(int i=1;i<=n;++i)belog[i]=i;
	for(int i=1;i<=m;++i)
		e[i].u=read(),e[i].v=read(),e[i].a=read(),e[i].b=read();
	sort(e+1,e+1+m);
	T1.solve();
	if(ans==INF)puts("-1");
	else printf("%d\n",ans);
	return 0;
}
